﻿package com.agileai.miscdp.hotweb.generator.treecontent;

import java.io.File;
import java.util.HashMap;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

import com.agileai.miscdp.NoOpEntityResolver;
import com.agileai.miscdp.hotweb.database.DBManager;
import com.agileai.miscdp.hotweb.domain.treecontent.ContentTableInfo;
import com.agileai.miscdp.hotweb.domain.treecontent.TreeContentFuncModel;
import com.agileai.miscdp.hotweb.generator.Generator;
import com.agileai.util.StringUtil;
import com.agileai.util.XmlUtil;
/**
 * 服务配置代码生成器
 */
public class TACServiceCfgGenerator implements Generator{
	private TreeContentFuncModel treeContentFuncModel = null;
	private String configFile = null;
	private String encoding = "UTF-8";
	private String projectName = null;;
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void generate() {
		try {
	        SAXReader saxReader = new SAXReader();
	        saxReader.setEntityResolver(new NoOpEntityResolver());
	        saxReader.setIncludeExternalDTDDeclarations(false);
	        saxReader.setValidation(false);
	        Document document = saxReader.read(new File(configFile));
	        String serviceId = treeContentFuncModel.getServiceId();
	        String serviceTargetId = serviceId.substring(0,serviceId.length()-7)+"Target";
	        
	        HashMap xmlMap = new HashMap();
	        xmlMap.put("s", "http://www.springframework.org/schema/beans");
	        XPath serviceTargetPath = document.createXPath("//s:beans/s:bean[@id='"+serviceTargetId+"']");
	        serviceTargetPath.setNamespaceURIs(xmlMap);
	        Node serviceTargetNode = serviceTargetPath.selectSingleNode(document);
	        if (serviceTargetNode != null){
	        	serviceTargetNode.getParent().remove(serviceTargetNode);
	        }
	        Element beansElement = (Element)document.selectSingleNode("//beans");
	        Element newServiceTarget = beansElement.addElement("bean");
	        String implClassName = treeContentFuncModel.getImplClassName();
	        newServiceTarget.addAttribute("id",serviceTargetId);
	        newServiceTarget.addAttribute("class",implClassName);
	        newServiceTarget.addAttribute("parent","baseService");
	        String sqlNameSpace = treeContentFuncModel.getSqlNamespace();
	        newServiceTarget.addElement("property").addAttribute("name","sqlNameSpace")
	        	.addAttribute("value",sqlNameSpace);
	        String tableName = treeContentFuncModel.getTreeTableName();
	        newServiceTarget.addElement("property").addAttribute("name","tableName")
        	.addAttribute("value",tableName);
	        
	        List<ContentTableInfo> contentTableInfos = treeContentFuncModel.getContentTableInfoList();
	        
	        Element tabIdAndTableNameMapping = newServiceTarget.addElement("property").addAttribute("name","tabIdAndTableNameMapping").addElement("map");
	        
	        for (int i=0;i < contentTableInfos.size();i++){
	        	ContentTableInfo contentTableInfo = contentTableInfos.get(i);
	        	String tabId = contentTableInfo.getTabId();
	        	String conTableName = contentTableInfo.getTableName();
	        	tabIdAndTableNameMapping.addElement("entry").addAttribute("key", tabId).addElement("value").setText(conTableName);	        	
	        }
	        DBManager dbManager = DBManager.getInstance(projectName);
	        String[] treePrimaryKeys = dbManager.getPrimaryKeys(tableName);
	        
	        Element tabIdAndColFieldMapping = newServiceTarget.addElement("property").addAttribute("name","tabIdAndColFieldMapping").addElement("map");;
	        for (int i=0;i < contentTableInfos.size();i++){
	        	ContentTableInfo contentTableInfo = contentTableInfos.get(i);
	        	String tabId = contentTableInfo.getTabId();
	        	String colField = contentTableInfo.getColField();
	        	if (StringUtil.isNullOrEmpty(colField)){
	        		colField = treePrimaryKeys[0];
	        	}
	        	tabIdAndColFieldMapping.addElement("entry").addAttribute("key", tabId).addElement("value").setText(colField);
	        }
	        
	        Element tabIdAndTableModeMapping = newServiceTarget.addElement("property").addAttribute("name","tabIdAndTableModeMapping").addElement("map");;
	        for (int i=0;i < contentTableInfos.size();i++){
	        	ContentTableInfo contentTableInfo = contentTableInfos.get(i);
	        	String tabId = contentTableInfo.getTabId();
	        	String tableMode = contentTableInfo.getTableMode();
	        	tabIdAndTableModeMapping.addElement("entry").addAttribute("key", tabId).addElement("value").setText(tableMode);
	        }
	        
	        XPath servicePath = document.createXPath("//s:beans/s:bean[@id='"+serviceId+"']");
	        servicePath.setNamespaceURIs(xmlMap);
	        Node serviceNode = servicePath.selectSingleNode(document);
	        if (serviceNode != null){
	        	serviceNode.getParent().remove(serviceNode);
	        }
	        Element newService = beansElement.addElement("bean");
	        newService.addAttribute("id",serviceId);
	        newService.addAttribute("parent","transactionBase");
	        newService.addElement("property").addAttribute("name","target")
	        	.addAttribute("ref",serviceTargetId);
	        XmlUtil.writeDocument(document, encoding, configFile);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void setConfigFile(String configFile) {
		this.configFile = configFile;
	}
	
	public void setProjectName(String projectName) {
		this.projectName = projectName;
	}

	public void setFuncModel(TreeContentFuncModel suFuncModel) {
		this.treeContentFuncModel = suFuncModel;
	}
}
